package com.anita.member.application.service;

import com.anita.member.application.command.MemberLoginCommand;
import com.anita.member.application.dto.MemberLoginResponse;
import com.anita.member.application.port.in.MemberLoginUseCase;
import com.anita.member.common.exception.BusinessException;
import com.anita.member.common.enums.Resp;
import com.anita.member.domain.model.member.*;
import com.anita.member.domain.repository.MemberRepository;
import com.anita.member.domain.repository.RefreshTokenRepository;
import com.anita.member.domain.service.JwtService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.net.NetUtil;
import java.util.Optional;

/**
 * @author qiu
 * @date 2025/10/20
 * @description
 */
@Slf4j
@Service
@Transactional
public class MemberLoginService implements MemberLoginUseCase {

    @Resource
    private MemberRepository memberRepository;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private JwtService jwtService;

    @Resource
    private RefreshTokenRepository refreshTokenRepository;

    @Override
    public MemberLoginResponse login(MemberLoginCommand command) {
        Optional<Member> memberOptional = memberRepository.findByName(Username.of(command.username()));
        if(memberOptional.isEmpty()){
            throw new BusinessException(Resp.USER_NOT_FOUND);
        }
        Member member = memberOptional.get();

        //验证密码
        if (!member.matchesPassword(command.password(), passwordEncoder)){
            throw new BusinessException(Resp.USER_PASSWORD_ERROR);
        }

        //检查会员状态
        if(member.getStatus().code() != 0){
            throw new BusinessException(Resp.USER_ACCOUNT_DISABLED);
        }

        //记录登录信息
        String clientIp = NetUtil.getMultistageReverseProxyIp(command.servletRequest().getRemoteAddr());
        //记录登录ip
        member.recordLogin(clientIp);
        memberRepository.save(member);

        //生成jwt token
        String accessToken = jwtService.generateAccessToken(JwtService.UserType.MEMBER, member.getId().value());
        String refreshToken = jwtService.generateRefreshToken(JwtService.UserType.MEMBER, member.getId().value());

        //存储refreshToken
        refreshTokenRepository.storeRefreshToken(JwtService.UserType.MEMBER, member.getId().value(), refreshToken);

        log.info("会员登录成功: {}  ip: {}", member.getUserName().getValue(),clientIp);

        return new MemberLoginResponse(accessToken, refreshToken);
    }
}
